#include "ResultStorage.h"

#include <sys/stat.h>
#include <sys/types.h>

#include <fstream>
using std::ofstream;

#include <sstream>
using std::ostringstream;

#include <iomanip>
using std::setw;
using std::setfill;

#include "../../../graphics/Pbm.h"
#include "../../../physics/cpm/Cell.h"
#include "../../../physics/cpm/Physics.h"
//#include "shapes/ShapeIdentifierGenerator3X3.h"
//#include "shapes/ShapeIdentifier.h"
#include "../../../physics/cpm/World.h"

#include "EmbryoIndividualDevelopment.h"

namespace GA {

/*
	ResultStorage
*/

/*	public	*/

ResultStorage::ResultStorage(int worldWidth, int worldHeight, int developmentLength, string directory) :
	_worldWidth(worldWidth),
	_worldHeight(worldHeight),
	_developmentLength(developmentLength),
	_directory(directory),
	_individualCount(0) {

	/* make directory */
	mkdir(directory.c_str(), 0755);

//	/* change to directory */
}

void ResultStorage::addIndividual(EmbryoIndividual const& individual) {

//	/* world */
//	World world(_worldWidth, _worldHeight);

//	/* physics */
//	Physics physics(world);

//	/* shape identifier */
//	ShapeIdentifierGenerator3X3& generator = ShapeIdentifierGenerator3X3::getInstance();
//	ShapeIdentifier* shapeIdentifier = generator.getNewShapeIdentifier();

	/* cell */
//	int cellSide = 1;
//	int cellSide = 3;
//	int cellSide = 6;
//	Cell* cell = new Cell(world, *shapeIdentifier, individual.getGenome(), cellSide * cellSide);

//	/* worldly cell */
//	world.addCell(cell);
//	int cellId = cell->getId();
//	int xCellOrigin = _worldWidth  / 2 - cellSide / 2;
//	int yCellOrigin = _worldHeight / 2 - cellSide / 2;
//	for(int i = 0; i != cellSide; ++i) {
//		for(int j = 0; j != cellSide; ++j) {
//			world.setTile(xCellOrigin + i, yCellOrigin + j, cellId);
//		}
//	}

//	/* run */
//	physics.run(_developmentLength);

	EmbryoIndividualDevelopment development(_worldWidth, _worldHeight, individual, _developmentLength);
	development.runAll();

	const World& world = development.getWorld();

	/* convert to PBM */
	Pbm pbm(_worldWidth, _worldHeight);
	for(int i = 0; i != _worldWidth; ++i) {
		for(int j = 0; j != _worldHeight; ++j) {
			pbm.set(i, j, world.grid(i, j));
		}
	}

	/* output */
	ostringstream oss;
//	oss.fill("0");
//	oss << _directory << "/Individual-" << setw(7) << _individualCount << ".pbm";
	oss << _directory << "/Individual-" << setfill('0') << setw(7) << _individualCount << ".pbm";
	ofstream file;
	file.open(oss.str().c_str());
//	file.open(oss.str().c_str(), std::ios_base::out);
	file << pbm.toString();
	file.close();

	++_individualCount;
//	delete shapeIdentifier;
}

} // GA

